/*
 * Copyright (c) 2018-2999 北京国电高科科技有限公司 All rights reserved.
 *
 * https://www.tqmall.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.gdgk.shop.api.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gdgk.shop.api.config.WxPayProperties;
import com.gdgk.shop.bean.enums.PayType;
import com.gdgk.shop.bean.model.*;
import com.gdgk.shop.common.util.Arith;
import com.gdgk.shop.dao.*;
import com.gdgk.shop.security.common.bo.UserInfoInTokenBO;
import com.gdgk.shop.security.common.util.AuthUserContext;
import com.gdgk.shop.api.config.ApiConfig;
import com.gdgk.shop.bean.app.param.PayParam;
import com.gdgk.shop.bean.pay.PayInfoDto;
import com.gdgk.shop.security.api.model.GdgkUser;
import com.gdgk.shop.security.api.util.SecurityUtils;
import com.gdgk.shop.service.PayService;
import com.gdgk.shop.service.ScoreService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.exception.HttpException;
import com.wechat.pay.java.core.exception.MalformedMessageException;
import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import com.gdgk.shop.common.response.ServerResponseEntity;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;
import java.util.List;

/**
 * @author lyh
 */
@RestController
@Component
@RequestMapping("/p/order")
@Tag(name = "订单接口")
@Slf4j
//@AllArgsConstructor
public class PayController {

//    private final PayService payService;
//
//    private final OrderSettlementMapper orderSettlementMapper;
//
//    @Value("${wx.mockPay.api}")
//    private String wxPayMock;

//    @Autowired
//    private UserMapper userMapper;
//
//    private final WxPayProperties properties;
//    private final OrderMapper orderMapper;
//
//    private final OrderItemMapper orderItemMapper;
//
//    private final ProductMapper productMapper;
//
//    private ScoreService scoreService;
//
//    private final JsapiServiceExtension service;

    @Autowired
    private PayService payService;


    @Autowired
    private OrderSettlementMapper orderSettlementMapper;

    @Value("${wx.mockPay.api}")
    private String wxPayMock;


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private WxPayProperties properties;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired

    private ProductMapper productMapper;

    @Autowired
    private ScoreService scoreService;

//    @Autowired
//    private JsapiServiceExtension service;

    @Autowired
    private ApiConfig apiConfig;


//    public PayController(PayService payService, OrderSettlementMapper orderSettlementMapper, WxPayProperties properties,
//                         OrderMapper orderMapper, OrderItemMapper orderItemMapper, ProductMapper productMapper, ScoreService scoreService,
//                         JsapiServiceExtension service) {
//        this.payService = payService;
//        this.orderSettlementMapper = orderSettlementMapper;
//        this.properties = properties;
//        this.orderMapper = orderMapper;
//        this.orderItemMapper = orderItemMapper;
//        this.productMapper = productMapper;
//        this.scoreService = scoreService;
//        this.service = service;
//    }

//    /**
//     * 支付接口
//     */
//    @PostMapping("/pay")
//    @Operation(summary = "根据订单号进行支付" , description = "根据订单号进行支付")
//    public ServerResponseEntity<Void> pay(@RequestBody PayParam payParam) {
//        GdgkUser user = SecurityUtils.getUser();
//        String userId = user.getUserId();
//
//
//        PayInfoDto payInfo = payService.pay(userId, payParam);
//        payService.paySuccess(payInfo.getPayNo(), "");
//        return ServerResponseEntity.success();
//    }

    /**
     * 积分或微信支付接口
     */
    @PostMapping("/pay")
    @Operation(summary = "根据订单号进行积分或微信支付", description = "根据订单号进行积分或微信支付")
    @SneakyThrows
    public ServerResponseEntity<PrepayWithRequestPaymentResponse> pay(@RequestBody PayParam payParam) {
        UserInfoInTokenBO user = AuthUserContext.get();
        String userId = user.getUserId();
        String openId = user.getWxOpenId();
        User customer = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserId, userId));
        PayInfoDto payInfo = payService.pay(userId, payParam);
        OrderSettlement orderSettlement = orderSettlementMapper.selectOne(new LambdaQueryWrapper<OrderSettlement>().eq(OrderSettlement::getPayNo, payInfo.getPayNo()));
        String orderNumber = orderSettlement.getOrderNumber();
        Order order = orderMapper.getOrderByOrderNumber(orderNumber);
        order.setPayType(payParam.getPayType());
        orderMapper.updateById(order);
        List<OrderItem> orderItems = orderItemMapper.listByOrderNumber(orderNumber);
        OrderItem orderItem = orderItems.get(0);
        long prodId = orderItem.getProdId();
        Product product = productMapper.selectOne(new LambdaQueryWrapper<Product>().eq(Product::getProdId, prodId));
        if (payParam.getPayType().equals(PayType.SCOREPAY.value())) {
            if (product.getProdPayType().equals(1)) {
                return ServerResponseEntity.showFailMsg("此商品不支持积分支付，请使用微信支付！");
            } else {
                //1.拿到商品对应的积分
                Integer prodScore = payInfo.getPayScore();
                //2.查询用户表数据库tz_user
                Integer userScore = customer.getScore();
                //3.用第二步查到的score - 商品对应的积分
                if (userScore - prodScore < 0) {
                    return ServerResponseEntity.showFailMsg("积分不足，请使用微信支付！");
                } else {
                    //4.update用户积分(调义珂接口)
                    String mobileNumber = customer.getUserMobile();
                    scoreService.subtractScoreByPay(mobileNumber, prodScore);
                    payService.paySuccess(payInfo.getPayNo(), "");
                    // 将tz_order_settlement->pay_amount update为0.00

                    return ServerResponseEntity.success();
                }
            }
        }

        //判断商品是否只支持积分支付
        if (product.getProdPayType().equals(2)) {
            return ServerResponseEntity.showFailMsg("此商品只支持积分支付，请使用积分支付！");
        }
        // 将tz_order_settlement->pay_score update为0
        orderSettlement.setPayScore(0);
        orderSettlementMapper.updateById(orderSettlement);

        Config config = new RSAAutoCertificateConfig.Builder()
                .merchantId(properties.getMchId())
                //.privateKeyFromPath(this.properties.getKeyPath())
                .privateKey(properties.getPrivateKey())
                .merchantSerialNumber(properties.getSerial())
                .apiV3Key(properties.getApiV3Key())
                .build();
        // 构建service
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        PrepayRequest orderRequest = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal((int) Arith.mul(payInfo.getPayAmount(), 100));
        orderRequest.setAmount(amount);
        orderRequest.setAppid(properties.getAppId());
        orderRequest.setMchid(properties.getMchId());
        orderRequest.setDescription("测试商品标题");
        orderRequest.setNotifyUrl(apiConfig.getDomainName() + "/notice/pay/order");
        orderRequest.setOutTradeNo(payInfo.getPayNo());
        Payer payer = new Payer();
        payer.setOpenid(openId);
        orderRequest.setPayer(payer);
        boolean wxPayStatus = true;
        PrepayWithRequestPaymentResponse response = null;
        try {
            response = service.prepayWithRequestPayment(orderRequest);
        } catch (HttpException e) { // 发送HTTP请求失败
            // 调用e.getHttpRequest()获取请求打印日志或上报监控，更多方法见HttpException定义
            log.error(e.getHttpRequest().toString());
            wxPayStatus = false;
        } catch (ServiceException e) { // 服务返回状态小于200或大于等于300，例如500
            // 调用e.getResponseBody()获取返回体打印日志或上报监控，更多方法见ServiceException定义
            log.error(e.getResponseBody());
            wxPayStatus = false;
        } catch (MalformedMessageException e) { // 服务返回成功，返回体类型不合法，或者解析返回体失败
            // 调用e.getMessage()获取信息打印日志或上报监控，更多方法见MalformedMessageException定义
            log.error(e.getMessage());
            wxPayStatus = false;
        }
        if (!wxPayStatus) {
            ServerResponseEntity.showFailMsg("微信支付失败!");
        }
        return ServerResponseEntity.success(response);
    }

    /**
     * 普通支付接口
     */
    @PostMapping("/normalPay")
    @Operation(summary = "根据订单号进行支付", description = "根据订单号进行支付")
    public ServerResponseEntity<Boolean> normalPay(@RequestBody PayParam payParam) {

        GdgkUser user = SecurityUtils.getUser();
        String userId = user.getUserId();
        PayInfoDto pay = payService.pay(userId, payParam);

        // 根据内部订单号更新order settlement
        payService.paySuccess(pay.getPayNo(), "");

        return ServerResponseEntity.success(true);
    }
}
